home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk67 / ssur1-1 / ssur.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  5KB  |  295 lines

  1. /* Little Usenet Reader */
  2.  
  3. #ifdef IBMPC
  4. #include <stdlib.h>
  5. #define READ_MODE    "rb"
  6. #define WRITE_MODE    "wb"
  7. #define SCREEN_ROWS    24
  8. #define SCREEN_COLS    80
  9. #endif
  10.  
  11. #ifdef AMIGA
  12. #include <fcntl.h>
  13. #define SEEK_SET 0
  14. #define READ_MODE    "r"
  15. #define WRITE_MODE    "w"
  16. #define SCREEN_ROWS    22
  17. #define SCREEN_COLS    78
  18. char    *gets();
  19. #endif
  20.  
  21. #include <stdio.h>
  22.  
  23. typedef unsigned char BOOL;
  24. #define FALSE (0)
  25. #define TRUE (!FALSE)
  26. #define MAX_LINE_LEN 256
  27. #define BACK_BUF    256
  28. #define FF    (12)
  29. #define BS  (8)
  30. #ifdef MEDDLE
  31. #define DPRT(x) x
  32. #else
  33. #define DPRT(x)
  34. #endif
  35.  
  36. #define MIN(x,y) (x) > (y) ? (y) : (x)
  37.  
  38. long    start_msg;
  39. long    end_msg;
  40. int        start_col;
  41. int        end_col;
  42. int        start_row;
  43. int        end_row;
  44. FILE    *fpin;
  45. FILE    *fpout;
  46. int        msg_count;
  47. char    msg_brk[MAX_LINE_LEN];
  48. int        msg_brk_len;
  49.  
  50.  
  51. long get_end_msg(begin)
  52. long    begin;
  53. {
  54.     int        i;
  55.     long    loc;
  56.     char    s[MAX_LINE_LEN];
  57.  
  58.     fseek (fpin, begin, SEEK_SET);
  59.     loc = begin;
  60.     for (;;)
  61.     {
  62.         i = fgetc (fpin);
  63.         if (i == msg_brk[0])
  64.         {
  65.             s[0] = i;
  66.             if (msg_brk_len == 1)
  67.                 return (ftell(fpin) - 1L);
  68.             i = fread (s+1, msg_brk_len - 1, 1, fpin);
  69.             if (i == 0 || strncmp (msg_brk, s, msg_brk_len) == 0)
  70.                 return (ftell(fpin) - (long) msg_brk_len);
  71.             fseek (fpin, ftell(fpin) - (long)msg_brk_len + 1L, SEEK_SET);
  72.         }
  73.     }
  74. }
  75.  
  76. long get_prev_msg(begin)
  77. long    begin;
  78. {
  79.     int        i;
  80.     char    s[BACK_BUF];
  81.     int        limit;
  82.     int        last_ff;
  83.  
  84.     begin -= 1L;
  85.     for (;;)
  86.     {
  87.         if (begin <= 0L)
  88.             return(0L);
  89.         begin -= (long) BACK_BUF;
  90.         if (begin < 0L)
  91.         {
  92.             limit = (int) (BACK_BUF +  begin);
  93.             begin = 0L;
  94.         }
  95.         else
  96.             limit = BACK_BUF;
  97.  
  98.         fseek (fpin, begin, SEEK_SET);
  99.         i = fread (s, 1, BACK_BUF, fpin);
  100.         limit = limit > i ? i : limit;
  101.         limit -= msg_brk_len;
  102.  
  103.         for (i = 0, last_ff = -1 ; i <= limit; i++)
  104.         {
  105.             if (s[i] == msg_brk[0])
  106.                 if (strncmp(&s[i], msg_brk, msg_brk_len) == 0)
  107.                     last_ff = i;
  108.         }
  109.         if (last_ff != -1)
  110.             return (begin + (long) last_ff + 1L);
  111.         if (begin <= 0L)
  112.             return(0L);
  113.         begin += ( (long)msg_brk_len - 1L);
  114.     }
  115. }
  116.  
  117.  
  118. BOOL out_page(fp,lines)
  119. FILE    *fp;
  120. int        lines;
  121. {
  122.     int        i,j;
  123.     char    s[MAX_LINE_LEN];
  124.  
  125.     if (ftell(fpin) >= end_msg)
  126.         return(FALSE);
  127.  
  128.     for (i = 0, j = MIN((end_col - start_col), MAX_LINE_LEN); 
  129.         i < lines || lines == 0; 
  130.         i++)
  131.     {
  132.         fgets (s, j, fpin);
  133.         fputs (s, fp);
  134.         if (end_msg <= ftell(fpin))
  135.             break;
  136.     }
  137. }
  138.  
  139.  
  140. BOOL out_msg(fp,lines)
  141. FILE    *fp;
  142. int        lines;
  143. {
  144.     int        i,j;
  145.     char    s[MAX_LINE_LEN];
  146.  
  147.     end_msg = get_end_msg(start_msg);
  148.     fseek (fpin, start_msg > (long)msg_brk_len ? 
  149.         start_msg - (long)msg_brk_len : 0L, 
  150.         SEEK_SET);
  151.  
  152.     if (start_msg >= end_msg)
  153.         return (FALSE);
  154.  
  155.     out_page (fp,lines);
  156. }
  157.  
  158.  
  159. BOOL next_page()
  160. {
  161.     int        i,j;
  162.     char    s[MAX_LINE_LEN];
  163.  
  164.     fprintf(stdout,"===== Start of message %d\n", msg_count);
  165.     start_msg = end_msg + 1L;
  166.     return(out_msg(stdout,end_row - start_row));
  167. }
  168.  
  169. BOOL write_page()
  170. {
  171.     int        ret;
  172.     ret = out_msg(fpout,0);
  173.     fputc ((int)FF, fpout);
  174.     return(ret);
  175. }
  176.  
  177. int close_all()
  178. {
  179. #ifdef AMIGA
  180.     set_con();
  181. #endif
  182.     fclose (fpin);
  183.     fclose (fpout);
  184.     exit(0);
  185. }
  186.  
  187. int get_one_char(fp)
  188. FILE    *fp;
  189. {
  190. #ifdef IBMPC
  191.     return(bdos(8));
  192. #endif
  193.  
  194. #ifdef AMIGA
  195.     unsigned char        c;
  196.     struct FileHandle    *fh;
  197.  
  198.     fh = (struct FileHandle *) _devtab[fileno(fp)].fd;
  199.     for (;;)
  200.     {
  201.         if (WaitForChar(fh, 1000L))
  202.         {
  203.             Read (fh, &c, 1L);
  204.             return ((int) c);
  205.         }
  206.     }
  207. #endif
  208. }
  209.  
  210. help()
  211. {
  212.     printf ("ssur (small simple usenet reader)  version 1.1\n");
  213.     printf ("Syntax: ssur [infile] [outfile] [message start string]\n\n");
  214.     printf ("[message start string] defaults to a Form feed character\n");
  215.     printf ("Key:      Use:\n");
  216.     printf ("n         Print first page of next message\n");
  217.     printf ("w         Write message to output file\n");
  218.     printf ("BACKSPACE Display first page of previous message\n");
  219.     printf ("b         Same as BACKSPACE\n");
  220.     printf ("SPACE     Display next screen of current message\n");
  221.     printf ("h         Display this help screen\n");
  222.     printf ("q         Quit\n");
  223. }
  224.  
  225. main (argc, argv)
  226. int        argc;
  227. char    **argv;
  228. {
  229.     int        c;
  230.  
  231. #ifdef AMIGA
  232.     set_raw();
  233. #endif
  234.     start_msg = 0L;
  235.     end_msg = -1L;
  236.     start_row = 1;
  237.     end_row = SCREEN_ROWS;
  238.     start_col = 1;
  239.     end_col = SCREEN_COLS;
  240.     help();
  241.     if (argc < 3)
  242.         exit (3);
  243.     fpin = fopen (argv[1], READ_MODE);
  244.     if (fpin == NULL)
  245.         exit(1);
  246.     fpout = fopen (argv[2], WRITE_MODE);
  247.     if (fpout == NULL)
  248.         exit(2);
  249.     if (argc == 4)
  250.         strcpy(msg_brk, argv[3]);
  251.     else
  252.     {
  253.         msg_brk[0] = FF;
  254.         msg_brk[1] = NULL;
  255.     }
  256.     msg_brk_len = strlen(msg_brk);
  257.     for (msg_count = 0;;)
  258.     {
  259.         c = get_one_char(stdin);
  260.         switch (c & 0xff)
  261.         {
  262.         case (int)'w':
  263.             msg_count++;
  264.             write_page();
  265.             next_page();
  266.             break;
  267.         case (int)'h':
  268.             help();
  269.             break;
  270.         case (int)'b':
  271.         case (int)BS:
  272.             msg_count -= msg_count > 1 ? 1 : 0;
  273.             end_msg = get_prev_msg(start_msg) - 1L;
  274.             next_page();
  275.             break;
  276.         case (int)' ':
  277.             if (! (out_page(stdout, end_row - start_row)))
  278.                 fprintf(stdout,"===== End of message %d\n",msg_count);
  279.             break;
  280.         case (int)'n':
  281.             msg_count++;
  282.             if (! (next_page()))
  283.             {
  284.                 fprintf(stdout,"===== End of last message\n");
  285.                 msg_count--;
  286.             }
  287.             break;
  288.         case (int)'q':
  289.             close_all();
  290.             break;
  291.         }
  292.     }
  293.     close_all();
  294. }
  295.